package service

import (
	"context"
	"fmt"
	"time"

	"image-sever-grpc/image-web-server/config"
	models "image-sever-grpc/image-web-server/dao"
	"image-sever-grpc/image-web-server/dao/model"
	oss "image-sever-grpc/oss-server/proto"
)

// ShareService 分享服务
type ShareService struct{}

// GetUserShares 获取用户的所有分享记录
func (s *ShareService) GetUserShares(userID int64, page, limit int) ([]model.Share, int64, error) {
	// 直接调用模型层方法查询该用户的分享记录
	shares, total, err := models.GetSharesByUserID(userID, page, limit)
	if err != nil {
		return nil, 0, fmt.Errorf("获取分享记录失败: %w", err)
	}
	return shares, total, nil
}

// STSCredential STS临时凭证结构
type STSCredential struct {
	AccessKeyID     string `json:"access_key_id"`
	AccessKeySecret string `json:"access_key_secret"`
	SecurityToken   string `json:"security_token"`
	Expiration      string `json:"expiration"` // 过期时间(UTC格式)
	Region          string `json:"region"`
	Bucket          string `json:"bucket"`
}

// GetUploadCredentials 获取上传用的STS凭证
// 权限限制：仅允许向用户目录上传文件
func (s *ShareService) GetUploadCredentials(userId int64, wpsSID string, expiration int) (*STSCredential, error) {
	// 1. 先通过 gRPC 获取 oss-server 中的 Bucket 信息（关键修改）
	bucket, err := s.getBucketFromOSSServer()
	if err != nil {
		return nil, fmt.Errorf("获取存储桶信息失败: %w", err)
	}

	// 2. 生成资源路径（使用从 oss-server 获取的 bucket）
	resource := fmt.Sprintf("acs:oss:*:*:%s/%d_%s/*", bucket, userId, wpsSID)

	// 3. 调用获取 STS 凭证的逻辑
	return s.getSTSCredentials(
		userId,
		"oss:PutObject", // 仅允许上传操作
		resource,
		expiration,
	)
}

// getBucketFromOSSServer 通过 gRPC 从 oss-server 获取 Bucket 名称
func (s *ShareService) getBucketFromOSSServer() (string, error) {
	// 检查 OSS 客户端是否初始化
	if config.OSSClient == nil {
		return "", fmt.Errorf("OSS 客户端未初始化")
	} else {
		fmt.Println("hello,yuanzhihua，袁志华护卫神无拘无束")
	}

	// 调用 gRPC 接口获取 Bucket 信息（需要在 oss-server 的 proto 中新增该接口）
	ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
	defer cancel()

	resp, err := config.OSSClient.GetBucketInfo(ctx, &oss.GetBucketInfoRequest{})
	if err != nil {
		return "", fmt.Errorf("调用 oss-server 获取 Bucket 失败: %w", err)
	}

	if resp.Bucket == "" {
		return "", fmt.Errorf("oss-server 返回空的 Bucket 名称")
	}

	return resp.Bucket, nil
}

// getSTSCredentials 通过 gRPC 调用 oss-server 获取 STS 凭证
func (s *ShareService) getSTSCredentials(userId int64, action, resource string, expiration int) (*STSCredential, error) {
	// 检查 OSS 客户端是否初始化
	if config.OSSClient == nil {
		return nil, fmt.Errorf("OSS 客户端未初始化")
	}

	// 调用 gRPC 接口
	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
	defer cancel()

	resp, err := config.OSSClient.GetSTSCredentials(ctx, &oss.GetSTSCredentialsRequest{
		UserId:     userId,
		Action:     action,
		Resource:   resource,
		Expiration: int32(expiration),
	})

	if err != nil {
		return nil, fmt.Errorf("调用 OSS 服务失败: %w", err)
	}

	// 处理错误响应
	if !resp.Error.Success {
		return nil, fmt.Errorf("获取 STS 凭证失败: %s", resp.Error.ErrorMsg)
	}

	// 转换为本地结构体
	return &STSCredential{
		AccessKeyID:     resp.Credential.AccessKeyId,
		AccessKeySecret: resp.Credential.AccessKeySecret,
		SecurityToken:   resp.Credential.SecurityToken,
		Expiration:      resp.Credential.Expiration,
		Region:          resp.Credential.Region,
		Bucket:          resp.Credential.Bucket, // 这里也可以直接使用从 oss-server 返回的 Bucket
	}, nil
}
